﻿#ifndef ICOM_H
#define ICOM_H

#include <QObject>
#include "../Base/tlv.h"

/**
 * @brief The ICom class
 * 抽象通信类，Tlv将不再局限于串口通信
 *
 * 必须要实现的方法：
 * bool isOpen() const;
 * QString hwName() const;
 * void open();
 * void close();
 * void IWrite(const QByteArray& data);
 *
 * 必须要连接的槽函数（当接收到数据时，请立即将数据传给该槽函数！）
 * void onReadyRead(const QByteArray& data);
 */
class ICom : public QObject
{
    Q_OBJECT
public:
    explicit ICom(QObject *parent = nullptr);
    virtual ~ICom();

    virtual bool isOpen() const = 0;
    virtual QString hwName() const = 0;

    static uint16_t checksum(const QByteArray& data);
    static QString ERR_NOT_OPEN();

public slots:
    virtual void open() = 0;
    virtual void close() = 0;
    void write(const Tlv& tlv);
    void write(const TlvTag& tag, const QByteArray& value);

signals:
    void frameDone();
    void dataSend(const Tlv&);
    void dataReceived(const Tlv&);
    void errorOccurred(const QString&);
    void opened();
    void closed();

protected slots:
    virtual void IWrite(const QByteArray& data) = 0;
    void onReadyRead(const QByteArray& data);

protected:
    void parse(const QByteArray&);
    QByteArray generate(const Tlv&);

private:
    QByteArray m_buffer; // 缓冲区
};

#endif // ICOM_H
